use axum::Json;
use axum::response::{IntoResponse, Response};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct AppResponse<T>{
    pub code: i32,
    pub message: String,
    pub data: Option<T>,
}

impl <T> AppResponse<T> {
    pub fn new(code: i32, message: String, data: Option<T>) -> AppResponse<T> {
        AppResponse { code, message, data }
    }
    pub fn ok<M: AsRef<str>>(message: M, data: Option<T>) -> AppResponse<T> {
        AppResponse::new(0, String::from(message.as_ref()), data)
    }
    pub fn err<M: AsRef<str>>(message: M) -> AppResponse<T> {
        AppResponse::new(-1, String::from(message.as_ref()), None)
    }
}

impl<T: Serialize> IntoResponse for AppResponse<T> {
    fn into_response(self) -> Response {
        let body: Json<AppResponse<T>> = axum::Json(self);
        body.into_response()
    }
}
